package com.wxapp.common.core.annotation.resolver;

import com.github.benmanes.caffeine.cache.Cache;
import com.wxapp.common.base.util.jackson.JacksonUtil;
import com.wxapp.common.base.util.md5.Md5Util;
import com.wxapp.common.base.util.redis.RedisUtil;
import com.wxapp.common.constant.constant.CatchCommonConstant;
import com.wxapp.common.core.annotation.DelCatch;
import com.wxapp.common.core.annotation.util.SpELUtil;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

/**
 * @author lgl
 * @Description
 * @Datetime 2023/9/8 11:01
 * @Modified By
 */
@Component
@Aspect
@RequiredArgsConstructor
public class DelCatchAspect {
    private final RedisUtil redisUtil;
    private final Cache<String, Object> caffeineCache;

    @Pointcut("@annotation(com.wxapp.common.core.annotation.DelCatch)")
    private void pointCut() {
    }

    /**
     * 在切入环绕通知
     */
    @Around(value = "pointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        //先执行方法 在删除缓存
        Object[] args = joinPoint.getArgs();
        var object=joinPoint.proceed(args);
        var aCatch = getCatchMethod(joinPoint);
        var annotation = aCatch.getAnnotation(DelCatch.class);
        String value = annotation.key();
        if (value != null && !"".equals(value)) {
            value = SpELUtil.parseExpression(value, aCatch, args);
        } else {
            for (Object arg : args) {
                value += Md5Util.md5(JacksonUtil.toJSONString(arg));
            }
        }
        removeCache(Md5Util.md5(value));
        return object;
    }

    public void removeCache(String key) {
        if (key == null || "".equals(key)) {
            return;
        }
        key = CatchCommonConstant.PROJECT_CATCH + key;
        caffeineCache.invalidate(key);
        redisUtil.del(key);
    }

    private Method getCatchMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        //处理方法参数，如果是User就进行加密处理
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        return signature.getMethod();
    }
}
